#coding=utf-8

"""
电子发票的测试
输入： 库文件，pdfdir和truthdir, 直接出具一份报告;
"""

import os
import sys
import codecs
import logging
import argparse
import shutil

logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='pdf_evaluate_report.txt',
                filemode='w')

def run(jarpath, pdfdir):
    """
    given a dir, run all the pdf files and save 
    """
    rsltdir = os.path.join(os.path.dirname(pdfdir),  os.path.basename(pdfdir) + "_rslt")
    if os.path.exists(rsltdir):
        # print("result exists! please remove first........")
        # exit()
        shutil.rmtree(rsltdir)
    
    pdfs = os.listdir(pdfdir)
    os.makedirs(rsltdir)

    for index,  pdf in enumerate(pdfs):
        print("{}: handle {}".format(index, pdf))
        pdfpath = os.path.join(pdfdir, pdf)
        rsltpath = os.path.join(rsltdir, pdf.replace('pdf', 'txt'))
        # print(pdfpath)
        # print(rsltpath)

        command = "java -jar {} {} {}".format(jarpath, pdfpath, rsltpath)
        os.system(command)
 
def getlines(file):
    """
    get file content
    """
    with open(file, 'r') as r:
        lines = r.readlines()
    
    return lines

def compare(rslttxt,  truthtxt):
    """
    given rslttxt and truthtxt, compare each item
    """    
    rsltlines = getlines(rslttxt)
    truthlines = getlines(truthtxt)

    vec = []
    for index in range(len(truthlines) - 3):
        x = (rsltlines[index].strip('\n'))
        y = (truthlines[index].strip(' \r\n').lstrip('\xef\xbb\xbf'))
        
        if not cmp(x, y):
            vec.append(1)
        else:
            vec.append(0)
    
    return len(truthlines) - 3, vec

def Evaluate(libpath, pdfdir, truthdir):
    #1. check if the lib exist
    if os.path.exists(libpath):
        logging.info("lib exists.")
        logging.info("lib path: {}".format(libpath))
    else:
        logging.info('lib does not exists, exit')
        exit()
    
    #2. check if the pdfdir exist
    if os.path.exists(pdfdir):
        logging.info("pdfdir exists.")
        logging.info("pdfdir : {}".format(pdfdir))
    else:
        logging.info('pdfdir does not exists, exit')
        exit()
    
    #3. check if the truthdir exist
    if os.path.exists(truthdir):
        logging.info("truthdir exists.")
        logging.info("truthdir : {}".format(truthdir))
    else:
        logging.info('truthdir does not exists, exit')
        exit()

    #4. check pdfdir number and truthdir number
    pdfs = os.listdir(pdfdir)
    logging.info('Num of pdf file in pdfdir is: {}'.format(len(pdfs)))

    truths = os.listdir(truthdir)
    logging.info('Num of truth file in truthdir is: {}'.format(len(truths)))

    #5.analysis
    pdf_alone = []
    pdf_truth = []

    for i, pdf in enumerate(pdfs):
        truth = pdf.replace('pdf', 'txt')
        if truth in truths:
            logging.info("{}: {}  <-----> {}:  exits.".format(i, pdf, truth))
            pdf_truth.append(pdf)
            truths.remove(truth)
        else:
            logging.info("{}: {}  <-----> {}:  Not exits.".format(i, pdf, truth))
            pdf_alone.append(pdf)
    
    truth_alone = truths

    logging.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
    logging.info("In summary: ")
    logging.info("pdf and truth both exist: {} ".format(len(pdf_truth)))
    for pdf in pdf_truth:
        logging.info("{}   {}".format(pdf, pdf.replace("pdf", "txt")))

    logging.info("pdf exist only: {}".format(len(pdf_alone)))
    for pdf in pdf_alone:
        logging.info(pdf)

    logging.info("truth exist only: {}".format(len(truth_alone)))
    for truth in truth_alone:
        logging.info(truth)
    logging.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n")

    #6. handle both exists
    logging.info("\n》》》》》》》》》》》》》》》》》》》》》handle {} both exits《《《《《《《《《《《《《《《《《《《《《《《".format(len(pdf_truth)))
    run(libpath, pdfdir)
    
    rsltdir = pdfdir + "_rslt"
    eval_vec = []
    
    for i, pdf in enumerate(pdf_truth):
        name = pdf.replace("pdf", 'txt')
        rslttxt = os.path.join(rsltdir, name)
        truthtxt = os.path.join(truthdir, name)

        #compare 
        num_item, temp = compare(rslttxt, truthtxt)
        eval_vec.append((temp, pdf))    #add the pdf name

        logging.info("{}: {},  {},  {}".format(i, pdf, rslttxt, truthtxt))
        logging.info(temp)

    #7. statitic item accuracy
    logging.info("\n\n")
    logging.info("<<<<<<<<<<<<<<<<<<<<<Item Accuracy Statistic>>>>>>>>>>>>>>>>>>>>>>>")
    for index in range(num_item):
        num_accurate = 0
        fault_pdfname = []
        for i in range(len(eval_vec)):
            if eval_vec[i][0][index] == 1:
                num_accurate +=1
            else:
                fault_pdfname.append(eval_vec[i][1])
        
        logging.info("Accuracy of item {}: {},  {}  {}".format(index,  num_accurate / (len(eval_vec) + 0.0), num_accurate, fault_pdfname))


if __name__=="__main__":
    
    # run("./TEST/53")
    # exit()

    # Parse command line arguments
    parser = argparse.ArgumentParser(
        description='Evaluate the item accuracy of given pdf dir and truth')

    parser.add_argument('--lib', required=False,
                        default="./pdfTools-1.0.6.jar",
                        metavar="/path/to/lib",
                        help='Path of the pdfTools lib')
    
    parser.add_argument('--pdfdir', required=False,
                        default="./TEST/53",
                        metavar="/path/to/pdfdir/for/evaluate",
                        help="Pdf dir for Evaluate")

    parser.add_argument('--truthdir', required=False,
                        default="./TEST/53_txt",
                        metavar="/path/to/truthdir/related/to/pdfdir",
                        help='Truth dir related to pdfdir for evaluate')
                        
    args = parser.parse_args()

    #core function
    Evaluate(args.lib, args.pdfdir, args.truthdir)